Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SortedPackedIntervalRtree to be thread-safe #746

Merged

Conversation

ivanveselovsky-tomtom
Copy link
Contributor

@ivanveselovsky-tomtom ivanveselovsky-tomtom commented Jun 21, 2021

SortedPackedIntervalRtree is not thread-safe, because the init method is not synchronized. This ensures that PreparedPolygon is thread-safe.

This also contains some cleanup for IndexedPointInAreaLocator.

Fixes #747.

Signed-off-by: veselovs [email protected]

Signed-off-by: veselovs <[email protected]>
@ivanveselovsky-tomtom ivanveselovsky-tomtom changed the title fix + demo test PreparedPolygon should be thread safe Jun 21, 2021
@dr-jts
Copy link
Contributor

dr-jts commented Jun 21, 2021

Can you describe the core changes which allow concurrency?

Comment on lines -135 to -140

private void printNode(IntervalRTreeNode node)
{
System.out.println(WKTWriter.toLineString(new Coordinate(node.min, level), new Coordinate(node.max, level)));
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this is a dead code, method never invoked.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just comment it out then. It may be used for debugging in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

@@ -102,15 +102,13 @@ public int locate(Coordinate p)
private synchronized void createIndex() {
if (index == null) {
index = new IntervalIndexedGeometry(geom);
// no need to hold onto geom
geom = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason the geometry can't be freed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason is that final geom field looks clearer, and the performance effect of nulling it is likely negligible.
However, it can be safely nulled, fixed in this way.

@@ -68,7 +66,7 @@ public void insert(double min, double max, Object item)
leaves.add(new IntervalRTreeLeafNode(min, max, item));
}

private void init()
private synchronized void init()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this is the key change for concurrency?

Copy link
Contributor Author

@ivanveselovsky-tomtom ivanveselovsky-tomtom Jun 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. From practical viewpoint only this change is enough to fix the problem.
Other changes make the code formally correct from concurrency viewpoint , + add some cleanup .

@@ -0,0 +1,67 @@
package org.locationtech.jts.geom.prep;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should go into the test.jts.perf.geom.prep package, because:

  • it requires custom VM settings
  • it is not guaranteed to reveal the issue on every run
  • it may require significant execution time

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

@ivanveselovsky-tomtom
Copy link
Contributor Author

Can you describe the core changes which allow concurrency?

Critical change is synchronizing method org.locationtech.jts.index.intervalrtree.SortedPackedIntervalRTree#init .
Before the fix absence of this synchronization was causing incorrect results under high concurrent load.

Other changes make the code more correct and reliable from the concurrency viewpoint, e.g "double-checked locking" in method org.locationtech.jts.algorithm.locate.IndexedPointInAreaLocator#createIndex can only work correctly if index field is volatile.

@dr-jts dr-jts changed the title PreparedPolygon should be thread safe Fix SortedPackedIntervalRtree to be thread-safe Jun 23, 2021
@dr-jts dr-jts merged commit 1bcdd78 into locationtech:master Jun 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PreparedPolygon is not thread safe
2 participants